from typing import Dict, Any, List
from intelli_port.data_layer.clients import mysql_execute_read, mysql_execute_write
from intelli_port.commons.audit import write_ops_log, audit_event
from intelli_port.robot_control.executor import create_robot_executor


def autoschedule_pending_requests() -> Dict[str, Any]:
    assigned: List[Dict[str, Any]] = []
    try:
        execu = create_robot_executor()
        reqs = mysql_execute_read(
            "SELECT id, service_type, location FROM service_requests WHERE status='pending' ORDER BY priority DESC, id ASC LIMIT 20",
            fetch="all",
        ).get("rows", [])
        robots = mysql_execute_read(
            "SELECT id, serial, location, battery, status FROM robots WHERE status='idle' ORDER BY battery DESC",
            fetch="all",
        ).get("rows", [])
        if not reqs or not robots:
            return {"assigned": assigned, "ok": False}
        ridx = 0
        for r in reqs:
            req_id = int(r[0])
            st = str(r[1] or "")
            rob = robots[ridx % len(robots)]
            rob_id = int(rob[0])
            mysql_execute_write(
                "UPDATE service_requests SET status='assigned', robot_id=%s, assigned_at=NOW() WHERE id=%s",
                (rob_id, req_id),
            )
            mysql_execute_write(
                "INSERT INTO robot_tasks(robot_id, type, payload, priority, status, scheduled_at) VALUES(%s,%s,%s,%s,%s,NOW())",
                (rob_id, st, "{}", 5, "scheduled"),
            )
            assigned.append({"request_id": req_id, "robot_id": rob_id, "service_type": st})
            try:
                execu.navigate_to(rob_id, {"task_id": req_id, "type": st, "target": r[2]})
            except Exception:
                pass
            ridx += 1
        write_ops_log("INFO", "scheduler.autoschedule", {"count": len(assigned)})
        audit_event("scheduler", "assign", "service_requests", {"count": len(assigned)}, result="success")
        return {"assigned": assigned, "ok": True}
    except Exception:
        return {"assigned": assigned, "ok": False}